package de.lehrbaum.outlokker.start;

import java.util.Calendar;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;

/**
 * The Surface shown at the start.
 * @author Ulic Quel-droma
 * @version 1.0
 */
public final class StartSurface extends SurfaceView implements Callback {
	private static final String TAG = StartSurface.class.getCanonicalName();
	
	/**
	 * The parts that can be started.
	 * 
	 * @author Ulic Quel-droma
	 * @version 1.0
	 */
	public static enum PART {
		/** The mail Part. */
		EMAIL,
		/** The contacts part. */
		CONTACTS,
		/** The calendar part */
		CALENDAR,
		/** The notes part */
		NOTES,
		/** The tasks part */
		TASKS
	}
	
	private SecundaryThread secundaryThread;
	private final OnPartClickListener listener;
	private boolean moving;
	private Rect centerRect;
	private int xVerticalSplit, yHorizontalSplit;
	
	/**
	 * Creates a new Start surface.
	 * 
	 * @param context The context.
	 * @param listener The listener that reacts to clicks.
	 */
	public StartSurface(Context context, OnPartClickListener listener) {
		super(context);
		SurfaceHolder holder = getHolder();
		holder.addCallback(this);
		moving = false;
		this.listener = listener;
	}
	
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
		Canvas c = null;
		try {
			c = holder.lockCanvas();
			// TODO Paint the pictures. I hope that although the api tells other way
			// two threads can paint.
		} finally {
			if (c != null)
				holder.unlockCanvasAndPost(c);
		}
	}
	
	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		secundaryThread = new SecundaryThread(holder, getContext());
	}
	
	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		secundaryThread.interrupt();
		while (secundaryThread.isAlive())
			try {
				secundaryThread.join();
			} catch (InterruptedException e) {
				Log.v(StartSurface.TAG, "The joining of the secundary Thread was interrupted.", e);
			}
		secundaryThread = null; // save space
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		Log.v(StartSurface.TAG, "Received motion event");
		switch (event.getAction()) {
		case MotionEvent.ACTION_UP:
			if (!moving) {
				// TODO find part
				listener.onPartClick(null);
				return true;
			} else {
				moving = false;
				return false;
			}
		case MotionEvent.ACTION_DOWN:
			return true;// otherwise i won't receive the up event.
		case MotionEvent.ACTION_MOVE:
			moving = true;
		default:
			return false;
		}
	}
	
	/**
	 * Starts the animation for the given part.
	 * 
	 * @param animatedPart
	 *           The part to animate.
	 * @param lengthInMillis
	 *           The length of the animation.
	 */
	public void startAnimation(PART animatedPart, long lengthInMillis) {
		secundaryThread.startAnimation(lengthInMillis, animatedPart);
	}
	
	/*
	 * Won't be used yet.
	 */
	private final class SecundaryThread extends Thread {
		private final SurfaceHolder holder;
		private final Context context;
		private long endTime;
		
		public SecundaryThread(SurfaceHolder holder, Context context) {
			this.holder = holder;
			this.context = context;
		}
		
		@Override
		public void run() {
			Canvas c = null;
			try {
				c = holder.lockCanvas();
				long timeInMillis = Calendar.getInstance().getTimeInMillis();
				while (!isInterrupted() && timeInMillis < endTime)
					// TODO animate
					timeInMillis = Calendar.getInstance().getTimeInMillis();
			} finally {
				if (c != null)
					holder.unlockCanvasAndPost(c);
			}
		}
		
		public void setSize(int width, int heigth) {
			
		}
		
		public void startAnimation(long lengthInMillis, PART animatedPart) {
			// Maybe with life progress update from the started app.
			endTime = Calendar.getInstance().getTimeInMillis() + lengthInMillis;
			try {
				start();
			} catch (IllegalStateException e) {
				Log.w(StartSurface.TAG,
						"The secundary threads animation was started althoug it was already started before.");
				// maybe create new thread and return it.
			}
		}
	}
	
	/**
	 * This listener will be informed if a part displayed by this surface is chosen.
	 * 
	 * @author Ulic Quel-droma
	 * @version 1.0
	 */
	public interface OnPartClickListener {
		public void onPartClick(PART partClicked);
	}
}